package com.zhangkang.stock.stocklib.view.index

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import com.zhangkang.stock.stocklib.data.KLineInfo
import com.zhangkang.stock.stocklib.view.CanvasTools
import com.zhangkang.stock.stocklib.view.IndexLineInfo
import com.zhangkang.stock.stocklib.view.IndexNameConfig
import com.zhangkang.stock.stocklib.view.KLineIndex
import com.zhangkang.stock.stocklib.view.KLineIndexInfo
import com.zhangkang.stock.stocklib.view.KLineViewColor
import com.zhangkang.stock.stocklib.view.KLineViewDimen
import com.zhangkang.stock.stocklib.view.PathPool
import com.zhangkang.stock.stocklib.view.RectPool

/**
 * @author : Android-张康
 * created on: 2023/5/8 16:14
 * description: K线中 RSI 绘制
 */
internal class KLineViewRSI(
    private val pathPool: PathPool,
    private val rectPool: RectPool,
    private val kLineViewColor: KLineViewColor,
    private val kLineViewDimen: KLineViewDimen,
    private val indexNameConfig: IndexNameConfig
) : KLineIndexInfo {

    private val mRSI1IndexLine = object : IndexLineInfo {
        override fun getName(): String {
            return "RSI1"
        }

        override fun getLineColor(): Int {
            return Color.parseColor("#282828")
        }

        override fun getIndexValue(kLineInfo: KLineInfo): Float {
            return kLineInfo.rsiList.values.toMutableList()[0].rsi
        }
    }

    private val mRSI2IndexLine = object : IndexLineInfo {
        override fun getName(): String {
            return "RSI2"
        }

        override fun getLineColor(): Int {
            return Color.parseColor("#F5BE51")
        }

        override fun getIndexValue(kLineInfo: KLineInfo): Float {
            return kLineInfo.rsiList.values.toMutableList()[1].rsi
        }
    }
    private val mRSI3IndexLine = object : IndexLineInfo {
        override fun getName(): String {
            return "RSI3"
        }

        override fun getLineColor(): Int {
            return Color.parseColor("#CE35DE")
        }

        override fun getIndexValue(kLineInfo: KLineInfo): Float {
            return kLineInfo.rsiList.values.toMutableList()[2].rsi
        }
    }

    private val mIndexLineList = mutableListOf(
        mRSI1IndexLine,
        mRSI2IndexLine,
        mRSI3IndexLine
    )

    private val indexLineInfoPath = mutableMapOf<IndexLineInfo, Path>()

    private var mMaxValue: Float = 0.0F

    private var mMinValue: Float = 0.0F

    private var priceItem: Float = 0.0F

    override fun getKLineIndex(): KLineIndex {
        return KLineIndex.RSI
    }

    override fun getProportion(): Int {
        return 1
    }

    override fun calculationMaxAndMinBefore(kLineInfo: KLineInfo) {
        mMaxValue = 0F
        mMinValue = 100F
    }

    override fun calculationMaxAndMin(kLineInfo: KLineInfo) {
        var maxValue = mMaxValue
        var minValue = mMinValue
        kLineInfo.rsiList.values.forEach {
            if (it.rsi > maxValue) {
                maxValue = it.rsi
            }
            if (it.rsi < minValue) {
                minValue = it.rsi
            }
        }
        mMaxValue = maxValue
        mMinValue = minValue
    }

    override fun calculationMaxAndMinAfter() {

    }

    /**
     * 绘制背景
     *
     * @param canvas 画布
     * @param startX 开始X
     * @param startY 开始Y
     * @param stopX 结束X
     * @param stopY 结束Y
     * @param linePaint 画布
     */
    override fun drawBackground(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        linePaint: Paint,
        textPaint: Paint
    ) {
        //绘制背景
        val backgroundPath = pathPool.acquire().apply {
            moveTo(startX, startY)
            lineTo(stopX, startY)
            lineTo(stopX, stopY)
            lineTo(startX, stopY)
            close()
        }
        linePaint.color = kLineViewColor.borderLineLineColor
        canvas.drawPath(backgroundPath, linePaint)
        pathPool.release(backgroundPath)

        val maxValue: Float = mMaxValue
        val minValue: Float = mMinValue
        //绘制最高价
        textPaint.textSize = kLineViewDimen.ordinateTextSize
        textPaint.color = kLineViewColor.ordinateTextColor
        val maxValueText = maxValue.toString()
        val textBoundsRect = rectPool.acquire()
        textPaint.getTextBounds(maxValueText, 0, maxValueText.length, textBoundsRect)
        val textStartY = textBoundsRect.height() + kLineViewDimen.textPaddingLine + startY
        canvas.drawText(
            maxValueText,
            startX + kLineViewDimen.textPaddingLine,
            textStartY,
            textPaint
        )
        //绘制最低价格
        val minValueText = minValue.toString()
        canvas.drawText(
            minValueText,
            startX + kLineViewDimen.textPaddingLine,
            stopY - kLineViewDimen.textPaddingLine,
            textPaint
        )
        rectPool.release(textBoundsRect)
    }

    override fun drawCurrentIndexInfo(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        linePaint: Paint,
        textPaint: Paint,
        marginTop: Float,
        span: Int,
        indexValueHorizontalSpace: Float,
        indexValueVerticalSpace: Float,
        kLineInfo: KLineInfo,
        kLineIsLine: Boolean
    ) {
        CanvasTools.drawIndicatorName(
            canvas = canvas,
            rectLeft = startX,
            startY = startY,
            stopY = stopY,
            linePaint = linePaint,
            textPaint = textPaint,
            rectPool = rectPool,
            indicatorName = "RSI",
            indexNameConfig = indexNameConfig
        )
        textPaint.textSize = kLineViewDimen.indexValueTextSize
        var indicatorStart = indexNameConfig.width + indexValueHorizontalSpace
        var drawTextInVerticalCenter: Int
        mIndexLineList.forEach { maInfo ->
            val currentString = "${maInfo.getName()}:${maInfo.getIndexValue(kLineInfo)}"
            textPaint.color = maInfo.getLineColor()
            drawTextInVerticalCenter = CanvasTools.drawTextInVerticalCenter(
                canvas, indicatorStart, startY, stopY, currentString, textPaint, rectPool = rectPool
            )
            indicatorStart += drawTextInVerticalCenter + indexValueHorizontalSpace
            indexLineInfoPath[maInfo] = pathPool.acquire()
        }
    }

    override fun beforeDrawItemContent(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        paint: Paint,
        candlestickWidth: Float,
        candlestickWidthSpace: Float,
        kLineInfo: KLineInfo,
        kLineIsLine: Boolean
    ) {
        val volumeRange = mMaxValue - mMinValue
        val drawHeight = stopY - startY
        priceItem = drawHeight / volumeRange
    }

    override fun drawItemContent(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        textPaint: Paint,
        linePaint: Paint,
        kLineInfo: KLineInfo,
        isFirst: Boolean,
        yangLineIsFill: Boolean,
        totalTranslateX: Float,
        candlestickWidth: Float,
        halfCandlestickWidth: Float,
        kLineIsLine: Boolean
    ) {
        //Path 的横坐标
        val pathX = halfCandlestickWidth + totalTranslateX
        indexLineInfoPath.forEach {
            val indexValue = it.key.getIndexValue(kLineInfo)
            val indexY = priceItem * (mMaxValue - indexValue) + startY
            val path = it.value
            if (isFirst) {
                if (indexY <= stopY) {
                    path.moveTo(pathX, indexY)
                } else {
                    path.moveTo(pathX, stopY)
                }
            } else {
                if (indexY < stopY) {
                    path.lineTo(pathX, indexY)
                }
            }
        }
    }

    override fun afterDrawItemContent(canvas: Canvas, paint: Paint) {
        //绘制各种指标线
        indexLineInfoPath.forEach {
            val maColor = it.key.getLineColor()
            val maPath = it.value
            paint.color = maColor
            canvas.drawPath(maPath, paint)
            pathPool.release(maPath)
        }
        indexLineInfoPath.clear()
    }
}